package lamma.lab.job;

import static junit.framework.Assert.assertEquals;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import lamma.lab2.job.AsyncStep;
import lamma.test.helper.FutureHelper;

import org.junit.Test;

/**
 * @author maxcellent
 *
 */
@Deprecated
public class ContextRunnerMultipleDependentJobs {

	private static class Job1 {
		
		private String a;
		
		private String b;

		private Future<String> resultFuture;
		
		@SuppressWarnings("unused")
		private String result1;
		
		@SuppressWarnings("unused")
		private String result2;
		
		@SuppressWarnings("unused")
		public Job1(String a, String b) {
			super();
			this.a = a;
			this.b = b;
		}
		
		@SuppressWarnings("unused")
		public void unexpectedCall() {
			throw new RuntimeException("not supposed to execute");
		}
		
		@SuppressWarnings("unused")
		@Step(serial=1)
		public AsyncStep fetch() {
			System.out.println("Job1 fetch");
			resultFuture = FutureHelper.mockFuture(500, a + b);
			return AsyncStep.Builder.fromFuture(resultFuture);
		}
		
		@SuppressWarnings("unused")
		@Step(serial=2)
		public void compile() throws InterruptedException, ExecutionException {
			System.out.println("Job1 compile");
			result1 = resultFuture.get();
			result2 = b + a;
		}
	}
	
	private static class Job2 {
		
		private String a;
		
		private String b;

		private String c;
		
		private Future<String> resultFuture;
		
		@SuppressWarnings("unused")
		private String result;
		
		@SuppressWarnings("unused")
		public Job2(String a, String b, String c) {
			super();
			this.a = a;
			this.b = b;
			this.c = c;
		}
		
		@SuppressWarnings("unused")
		public void unexpectedCall() {
			throw new RuntimeException("not supposed to execute");
		}
		
		@SuppressWarnings("unused")
		@Step(serial=1)
		public AsyncStep fetch() {
			System.out.println("Job2 fetch");
			resultFuture = FutureHelper.mockFuture(1000, a + b + c);
			return AsyncStep.Builder.fromFuture(resultFuture);
		}
		
		@SuppressWarnings("unused")
		@Step(serial=2)
		public void compile() throws InterruptedException, ExecutionException {
			System.out.println("Job2 compile");
			result = resultFuture.get();
		}
	}
	
	private class TestContext {
		
		@SuppressWarnings("unused")
		String input1;
		
		@SuppressWarnings("unused")
		String input2;
		
		@SuppressWarnings("unused")
		String input3;
		
		@FeedBy(job=Job1.class, params={"input1", "input2"}, result="result1")
		String job1Result1;
		
		@FeedBy(job=Job1.class, params={"input1", "input2"}, result="result2")
		String job1Result2;
		
		@FeedBy(job=Job2.class, params={"input2", "input3", "job1Result1"}, result="result")
		String job2Result;

		@FeedBy(job=Job1.class, params={"job1Result1", "input2"}, result="result1")
		String job12Result;	// another job 1 execution
		
		public TestContext(String input1, String input2, String input3) {
			super();
			this.input1 = input1;
			this.input2 = input2;
			this.input3 = input3;
		}
	}
	
	@Test
	public void test() {
		TestContext c = new TestContext("a", "b", "c");
		
		long start = System.currentTimeMillis();
		
		ContextRunner runner = new ContextRunner();
		runner.run(c);
		
		long end = System.currentTimeMillis();
		System.out.println(end - start);
		
		assertEquals("ab", c.job1Result1);
		assertEquals("ba", c.job1Result2);
		assertEquals("bcab", c.job2Result);
		assertEquals("abb", c.job12Result);
	}
}
